package top.lyjwn.todo.weinxin.utils;

import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import top.lyjwn.todo.common.utils.http.I509TrustManager;
import top.lyjwn.todo.weinxin.param.WXPayParam;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;

/**
 * ssl工具
 *
 * @author luoyujie
 *
 */
@Component
public class SSLUilt {

    private static Logger logger = LoggerFactory.getLogger(SSLUilt.class);

    @Autowired
    private WXPayParam wxPayParam;

    /**
     * 提交ssl连接请求,微信支付，使用默认的商户
     *
     * @param httpurl
     * @param str_xml
     * @return
     */
    public  String wxPayRequest(String httpurl, String str_xml) {
        String result = wxPayRequest(httpurl, str_xml, wxPayParam.getMchId(), wxPayParam.getCertCode());
        return result;
    }

    /**
     * 提交ssl连接请求,微信支付
     *
     * @param httpurl  请求地址
     * @param str_xml   //请求参数，xml格式
     * @param mch_id   //商户id
     * @param cert_code // 16进制证书码
     * @return 请求结果,异常为null
     */
    public  String wxPayRequest(String httpurl, String str_xml, String mch_id, String cert_code) {
        CloseableHttpClient client = null;
        HttpPost httpPost = null;
        try {
            // 解密出16进制原证书文件内容为字节数组
            byte[] bytes = Hex.decodeHex(cert_code.toCharArray());
            ByteArrayInputStream input = new ByteArrayInputStream(bytes);
            KeyStore clientTrustKeyStore = KeyStore.getInstance("PKCS12");
            clientTrustKeyStore.load(input, mch_id.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientTrustKeyStore, mch_id.toCharArray());
            TrustManager[] tm = { new I509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(kmf.getKeyManagers(), tm, new java.security.SecureRandom());
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            httpPost = new HttpPost(httpurl);
            httpPost.setEntity(new StringEntity(str_xml, StandardCharsets.UTF_8));
            CloseableHttpResponse response = client.execute(httpPost);
            StatusLine statusLine = response.getStatusLine();
            HttpEntity entity = response.getEntity();
            if (statusLine.getStatusCode() == 200) {
                return EntityUtils.toString(entity, StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            logger.error("SSL请求错误!请求地址" + httpurl + "。错误信息：" + e.getMessage());
        } finally {
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    logger.error("SSL连接失败!请求地址" + httpurl + "。错误信息：" + e.getMessage());
                }
            }
        }
        return null;
    }

    /**
     * 读取证书文件为16进制证书码
     *
     * @param file
     * @return
     */
    public static String readCertFile(InputStream file) {
        try {
            return Hex.encodeHexString(StreamUtils.copyToByteArray(file));
        } catch (IOException e) {
            return null;
        }
    }
}
